import { Injectable } from '@nestjs/common';
import { RedisUtil } from '../../../common/utils';

/**
 * Token 黑名单服务
 *
 * 使用 Redis 存储已登出的 Token，实现 Token 失效机制
 *
 * 功能：
 * - 将 Token 加入黑名单
 * - 检查 Token 是否在黑名单中
 * - 自动过期（与 Token 过期时间一致）
 */
@Injectable()
export class TokenBlacklistService {
  private readonly KEY_PREFIX = 'token:blacklist:';

  constructor(private readonly redisUtil: RedisUtil) {}

  /**
   * 将 Token 加入黑名单
   *
   * @param token JWT Token
   * @param expiresIn Token 过期时间（秒）
   *
   * @example
   * ```ts
   * await this.tokenBlacklistService.addToBlacklist(token, 604800); // 7天
   * ```
   */
  async addToBlacklist(token: string, expiresIn: number): Promise<void> {
    const key = this.getKey(token);
    // 存储 Token，设置过期时间与 Token 一致
    // 值设为 '1' 表示已失效
    await this.redisUtil.set(key, '1', expiresIn);
  }

  /**
   * 检查 Token 是否在黑名单中
   *
   * @param token JWT Token
   * @returns true 表示在黑名单中（已失效），false 表示有效
   *
   * @example
   * ```ts
   * const isBlacklisted = await this.tokenBlacklistService.isBlacklisted(token);
   * if (isBlacklisted) {
   *   throw new UnauthorizedException('Token 已失效');
   * }
   * ```
   */
  async isBlacklisted(token: string): Promise<boolean> {
    const key = this.getKey(token);
    const value = await this.redisUtil.get(key);
    return value !== null;
  }

  /**
   * 生成 Redis Key
   */
  private getKey(token: string): string {
    return `${this.KEY_PREFIX}${token}`;
  }
}

